package com.lagou.server;

import com.lagou.entity.RpcRequest;
import com.lagou.handler.UserServerHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author sxnan
 * @className UserServiceImpl
 * @description TODO
 * @date 2020/8/18
 */
public class UserServiceImpl implements IUserService {

    @Override
    public String sayHello(RpcRequest msg) {
        //根据对象中的对象名，方法名，参数类型，参数值等信息，通过反射完成调用
        String className = msg.getClassName();
        String methodName = msg.getMethodName();
        Object[] parameters = msg.getParameters();
        Class<?>[] parameterTypes = msg.getParameterTypes();
        try {
            Class<?> aClass = Class.forName(className);
            Object clazz  = aClass.newInstance();
            Method method = aClass.getMethod(methodName, parameterTypes);
            method.invoke(clazz, parameters);
        } catch (InstantiationException|InvocationTargetException|ClassNotFoundException|NoSuchMethodException|IllegalAccessException e) {
            e.printStackTrace();
        }
        return "success";
    }

    //创建一个启动方法
    public static void startServer(String hostName, int port) {
        try {
            //创建两个线程池对象
            NioEventLoopGroup bossGroup = new NioEventLoopGroup();
            NioEventLoopGroup eventLoopGroup = new NioEventLoopGroup();
            //创建服务端的启动引导对象
            ServerBootstrap bootstrap = new ServerBootstrap();
            //配置启动引导对象
            bootstrap.group(bossGroup,eventLoopGroup)
                    //设置了通道NIO
                    .channel(NioServerSocketChannel.class)
                    //创建监听channel
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                @Override
                protected void initChannel(SocketChannel ch) throws Exception {
                    //获取管道对象
                    ChannelPipeline p = ch.pipeline();
                    //给管道对象设置编码
                    p.addLast(new RpcDecoder(RpcRequest.class,new JSONSerializer()));
                    p.addLast(new StringEncoder());
                    //自定义一个channelHandler添加到通道中
                    p.addLast(new UserServerHandler());
                }
            });
            //绑定端口
            bootstrap.bind(hostName, port).sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}